package org.yelongframework.locale.china;

import java.math.BigDecimal;

import org.apache.commons.lang3.StringUtils;

/**
 * 中国金额工具类
 * 
 * @since 1.0.0
 */
public final class ChinaMoneyUtils {

	private static final String UNIT = "万仟佰拾亿仟佰拾万仟佰拾元角分";

	private static final String DIGIT = "零壹贰叁肆伍陆柒捌玖";

	private static final double MAX_VALUE = 9999999999999.99D;

	// ==================================================构造器==================================================

	private ChinaMoneyUtils() {
	}

	// ==================================================转大写==================================================

	/**
	 * 小写金额转大写金额
	 * 
	 * @param v 金额
	 * @return 大写的金额
	 */
	public static String toUppercase(double v) {
		if (v < 0 || v > MAX_VALUE) {
			throw new IllegalArgumentException("金额(" + v + ")不能小于0且不能大于最大值" + MAX_VALUE + "");
		}
		long l = Math.round(v * 100);
		if (l == 0) {
			return "零元整";
		}
		String strValue = l + "";
		// j用来控制单位
		int j = UNIT.length() - strValue.length();
		// i用来控制数
		int i = 0;
		String rs = "";
		boolean isZero = false;
		for (; i < strValue.length(); i++, j++) {
			char ch = strValue.charAt(i);
			if (ch == '0') {
				isZero = true;
				if (UNIT.charAt(j) == '亿' || UNIT.charAt(j) == '万' || UNIT.charAt(j) == '元') {
					rs = rs + UNIT.charAt(j);
					isZero = false;
				}
			} else {
				if (isZero) {
					rs = rs + "零";
					isZero = false;
				}
				rs = rs + DIGIT.charAt(ch - '0') + UNIT.charAt(j);
			}
		}
		if (!rs.endsWith("分")) {
			rs = rs + "整";
		}
		rs = rs.replaceAll("亿万", "亿");
		return rs;
	}

	// ==================================================转小写==================================================

	/**
	 * 大写金额转数字
	 * 
	 * @param chinese 中文金额
	 * @return 中文金额对应的数字
	 */
	public static String toNumberString(String chinese) {
		return toNumberBigDecimal(chinese).toString();
	}

	/**
	 * 大写金额转数字
	 * 
	 * @param chinese      中文金额
	 * @param defaultValue 默认值
	 * @return 中文金额对应的数字
	 */
	public static String toNumberString(String chinese, String defaultValue) {
		try {
			return toNumberBigDecimal(chinese).toString();
		} catch (IllegalArgumentException e) {
			return defaultValue;
		}
	}

	/**
	 * 大写金额转数字
	 * 
	 * @param chinese 中文金额
	 * @return 中文金额对应的数字
	 */
	public static Double toNumberDouble(String chinese) {
		return toNumberBigDecimal(chinese).doubleValue();
	}

	/**
	 * 大写金额转数字
	 * 
	 * @param chinese      中文金额
	 * @param defaultValue 默认值
	 * @return 中文金额对应的数字
	 */
	public static double toNumberDouble(String chinese, double defaultValue) {
		try {
			return toNumberBigDecimal(chinese).doubleValue();
		} catch (IllegalArgumentException e) {
			return defaultValue;
		}
	}

	/**
	 * 大写金额转数字
	 * 
	 * @param chinese 中文金额
	 * @return 中文金额对应的数字
	 */
	@SuppressWarnings("unused")
	public static BigDecimal toNumberBigDecimal(String chinese) {
		if (StringUtils.isBlank(chinese)) {
			throw new IllegalArgumentException("chinese cannot be blank");
		}
		// 移除计算干扰文字
		chinese = chinese.replace("元", "").replace("整", "");

		// 字符切割
		char[] wordCharArray = chinese.toCharArray();

		// 最终要返回的数字金额
		BigDecimal numberAmount = BigDecimal.ZERO;

		// 金额位标志量
		// 表示有分位
		boolean fen = false;
		// 表示有角位
		boolean jiao = false;
		// 表示个位不为0
		boolean yuan = false;
		// 表示有十位
		boolean shi = false;
		// 表示有百位
		boolean bai = false;
		// 表示有仟位
		boolean qian = false;
		// 表示有万位
		boolean wan = false;
		// 表示有亿位
		boolean yi = false;

		// 从低位到高位计算
		for (int i = (wordCharArray.length - 1); i >= 0; i--) {
			// 当前位金额值
			BigDecimal currentPlaceAmount = BigDecimal.ZERO;

			// 判断当前位对应金额标志量
			if (wordCharArray[i] == '分') {
				fen = true;
				continue;
			} else if (wordCharArray[i] == '角') {
				jiao = true;
				continue;
			} else if (wordCharArray[i] == '元') {
				yuan = true;
				continue;
			} else if (wordCharArray[i] == '拾') {
				shi = true;
				continue;
			} else if (wordCharArray[i] == '佰') {
				bai = true;
				continue;
			} else if (wordCharArray[i] == '仟') {
				qian = true;
				continue;
			} else if (wordCharArray[i] == '万') {
				wan = true;
				continue;
			} else if (wordCharArray[i] == '亿') {
				yi = true;
				continue;
			}

			// 根据标志量转换金额为实际金额
			double t = 0;
			if (fen) {
				t = toNumberIntByChar(wordCharArray[i]) * 0.01;
			} else if (jiao) {
				t = toNumberIntByChar(wordCharArray[i]) * 0.1;
			} else if (shi) {
				t = toNumberIntByChar(wordCharArray[i]) * 10;
			} else if (bai) {
				t = toNumberIntByChar(wordCharArray[i]) * 100;
			} else if (qian) {
				t = toNumberIntByChar(wordCharArray[i]) * 1000;
			} else {
				t = toNumberIntByChar(wordCharArray[i]);
			}
			currentPlaceAmount = new BigDecimal(t);
			// 每万位处理
			if (yi) {
				currentPlaceAmount = currentPlaceAmount.multiply(new BigDecimal(100000000));
			} else if (wan) {
				currentPlaceAmount = currentPlaceAmount.multiply(new BigDecimal(10000));
			}
			numberAmount = numberAmount.add(currentPlaceAmount);
			// 重置状态
			// yi = false; // 亿和万 不可重置 下次循环还会用到
			// wan = false;
			fen = false;
			jiao = false;
			shi = false;
			bai = false;
			qian = false;
			yuan = false;
		}
		return numberAmount.setScale(2, BigDecimal.ROUND_HALF_UP);
	}

	// ==================================================转数字==================================================

	/**
	 * 转换中文数字为阿拉伯数字
	 * 
	 * @param chinese 中文数字
	 * @return 中文数字对应的阿拉伯数字。如果没有对应的阿拉伯数字则返回-1
	 */
	public static int toNumberIntByChar(char chinese) {
		int number = -1;
		String s = String.valueOf(chinese);
		switch (s) {
		case "零":
			number = 0;
			break;
		case "壹":
			number = 1;
			break;
		case "贰":
			number = 2;
			break;
		case "叁":
			number = 3;
			break;
		case "肆":
			number = 4;
			break;
		case "伍":
			number = 5;
			break;
		case "陆":
			number = 6;
			break;
		case "柒":
			number = 7;
			break;
		case "捌":
			number = 8;
			break;
		case "玖":
			number = 9;
			break;
		default:
			throw new IllegalArgumentException("非法的中文数字:" + chinese);
		}
		return number;
	}

}